#ifndef _GATEWAY_CLIENT_H_
#define _GATEWAY_CLIENT_H_

#include "gateway_task.h"
#include "gateway_network_event.h"
#include "../mqttservice/mqttservice.h"
#include <boost/enable_shared_from_this.hpp>

typedef enum{CMDCONNECT = 0, CMDSTATE, CMDPING, CMDEND}CMDTYPE;
typedef enum{PULISH = 0, SUBSCRIBE, ONCONNECT}TASKTYPE;
typedef struct{
	std::string strcmddata;
	CMDTYPE cmdtype;
}CMDDATA;



class gateway_client : public gateway_stream_event, public IMqttEvent, public gateway_task,  public boost::enable_shared_from_this<gateway_task> {
	typedef enum cmdType{POWERON = 0XB3, PING = 0XB4, CARVOL = 0XB5, SCREENDATA = 0XB6, DICIDATA = 0XB7, RSP = 0X32}CMDTYPE;
	
struct powerOn{//上电
	std::string screenmac; //硬件id(上传数据屏幕MAC)
	std::string screenid;  //屏幕id
	std::string reporttime;//
	std::string commparm; //通讯参数
};

struct carVol{
	std::string screenmac; //硬件id(上传数据屏幕MAC)
	std::string localscid;   //本端品目id
	std::string remotescid;// 远端屏幕id
	std::string localTrafficVol;	//AtoB的车流量 --AtoBTrafficVolume
	std::string remoteTrafficVol;	//BtoA的车流量 --BtoATrafficVolume
	std::string reporttime;//
};

struct screenData{
	std::string screenmac;			//屏幕MAC --screenMac --硬件id
	std::string setNum;				//屏幕设置次数 --screenSetNum
	std::string scMac;				//屏幕mac(与screenMac不一样)
	std::string screenId;			//屏幕ID --screenId
	std::string screenVoltage;		//屏幕电源电压 --screenVoltage
	std::string sigNoise;			//信号噪音 --SigNoise
	std::string sigStrength;		//信号强度 --sigStrength
	std::string WLParm;				//无线参数 --WLParm
	std::string diciDist;			//地磁间距 --GeomagneticDist
	std::string spdlmt;				//限速 --speedLimit
	std::string localdelay;			//本测来车显示延时 --localDisplayDelay
	std::string remoteDelay;		//对侧来车显示延时 --remoteDisplayDelay
	std::string remoteCarDisplay;	//对侧车来屏幕显示 --remoteCarDisplay
	std::string localDisplay;		//对侧车来屏幕显示 --localDisplay
	std::string display;			//正常屏幕显示内容 --Display
	std::string reporttime;//
};

struct diciData{
	std::string screenmac;			//屏幕MAC --screenMac --硬件id
	std::string diciMac;			//地磁MAC  --GeomagneticMac
	std::string diciId;				//地磁ID --GeomagneticId
	std::string diciVoltage;		//地磁电压 --GeomagneticVoltage
	std::string sigNoise;			//信号噪音 --SigNoise
	std::string sigStrength;		//信号强度 --sigStrength
	std::string reporttime;//
};


typedef struct byteAttr{
	unsigned int screenMac;
	unsigned char sn;
	unsigned char srcAddr;
}ByteAttr;

	struct onmessage_data
	{
		std::string strid;
		ShadowActions actions;
		std::string payload;
	};
	struct pulish_data
	{
		char * data;
		int datalen;
		//std::string strjson;
	};
	struct event_data{
		TASKTYPE tasktype;
		void *data;
	};
	
public:
	explicit gateway_client(gateway_stream_ptr stream_ptr);
	virtual ~gateway_client();

	/**** gateway_stream_event ****/

	//网络连接事件
	virtual int stream_init();

	//网络断开事件
	virtual int stream_clean();

	//网络读取事件
	virtual int stream_read(unsigned char* data, unsigned int dataLen);

	/**** gateway_task ****/
	virtual int on_task(void* param);

public:
    
	int OnConnect(CMQTTService *mq, std::string strid, int rc);
	int OnDisconnect(CMQTTService *mq, std::string strid, int rc);
	int OnMessage(CMQTTService *mq, std::string strid, ShadowActions actions, std::string payload);
	int OnSubscribe(CMQTTService *mq, std::string strid, int mid, int qos_count, const int *granted_qos);
    int OnUnsubscribe(CMQTTService *mq, std::string strid, int mid);
	int OnPublish(CMQTTService *mq, std::string strid, int mid);

public:
	void close();	
	std::string get_addr(){return _addr;}
private:

	int handle_parse_packet(unsigned char* buf, unsigned int bufLen, unsigned int &used);

	int handle_mqtt_event(std::string strjson);

	int get_mqtt_config(MQTTCONFIG & mqttconfig);

	int gateway_packet_ack();

	int task_pulish(std::string strpulishdata);

	void task_onmessage(std::string strid, ShadowActions actions, std::string strpayload);

	std::string get_json_val(const std::string strJson, const std::string strkey);
	
	int deal_update(const std::string strJson);

	//int deal_get(const std::string strdevid, const std::string strJson);

	//int deal_ctrl(const std::string strdevid, const std::string strJson);
	
	//int send_cmd(std::string strcmd);

	int get_current_stamp();

	std::string byte2str(const unsigned char srcbyte, int decimal = 10);

	std::string int2str(const int srcint,int decimal = 10);

	std::string word2str(const unsigned short srcword, int decimal = 10);

	std::string dword2str(const unsigned int srcdword, int decimal = 10);
	//boost::shared_ptr<gateway_client> get_ptr();
private:
	unsigned int get_screenmac(const unsigned char* buf, int buflen);

	std::string get_reporttime(const unsigned char* buf, int buflen);

	int get_carvol(const unsigned char* buf, int buflen);

	unsigned short get_crc16(const unsigned char * buf, int buflen);

	int get_rsp_data(byteAttr byteattr, std::string &strdata);

	std::string get_poweron_json(powerOn poweron);

	std::string get_car_vol(carVol carvol);

	std::string get_screen_data(screenData screendata);

	std::string get_dici_data(diciData dicidata);

	int deal_poweron(std::string strdata, unsigned int &used);

	int deal_ping(std::string strdata, unsigned int &used);

	int deal_car_vol(std::string strdata, unsigned int &used);

	int deal_screen_data(std::string strdata, unsigned int &used);

	int deal_dici_data(std::string strdata, unsigned int &used);

	void display_buf_byhex(const unsigned char * buf, unsigned int len);
private:		
	std::string _host;
	bool _is_connected;
	unsigned short _port;
	std::string _addr;//ip:port
	unsigned short _ping_time;
	unsigned char _car_cnt_time;
	unsigned char _other_cnt_time;
	unsigned char _isn;
	//std::string _strdevid; 
	//std::string strkey;
	std::string _strhid;//硬件id
	MQTTCONFIG _mqttconfig;
	gateway_stream_ptr _stream_ptr;
	//cmqtt_service_ptr _mqtt_ptr;
	CMQTTService *_mqtt;

	boost::shared_ptr<gateway_client> _client_ptr;
};

typedef boost::shared_ptr<gateway_client>gateway_client_ptr;
#endif 